package com.gree.flowable.app.controller;

import com.gree.flowable.app.pojo.model.*;
import com.gree.flowable.app.pojo.vo.*;
import com.gree.flowable.app.services.IFlowableBpmnModelService;
import com.gree.flowable.app.services.IFlowableTaskService;
import com.gree.flowable.app.tools.constants.ReturnCode;
import com.gree.framework.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;

@RestController

@Api(tags = "流程任务管理API")
@RequestMapping("/rest/task")
public class IFlowableTaskApi extends FlowableBaseApi {
    @Autowired
    private TaskService taskService;

    @Autowired
    private IFlowableTaskService iFlowableTaskService;

    @Autowired
    private IFlowableBpmnModelService iFlowableBpmnModelService;

    /**
     * @Title: 查询代办工作
     */
    @PostMapping("/my-applying")
    @ApiOperation("查询代办工作")
    @ApiImplicitParam(name = "params", value = "查询信息VO", dataType = "QueryApplyMO")
    public PagerModel<TaskVO> getApplyingTasks(@RequestBody QueryApplyMO params){
        String systemName = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        if(systemName.equals("admin")){
            systemName = null;
        }
        if (StringUtils.isNotEmpty(systemName)){
            params.setSystemSn(systemName);
        }
        Query query = params.getQuery();

        PagerModel<TaskVO> applyingTasks = iFlowableTaskService.getApplyingTasks(params, query);
        return applyingTasks;
    }

    /**
     * @Title: 获取我已办工作列表
     */
    @PostMapping(value = "/my-applyed")
    @ApiOperation("获取我已办工作列表")
    @ApiImplicitParam(name = "params", value = "查询信息VO", dataType = "QueryApplyMO")
    public PagerModel<SolvedTaskVO> myProcessInstances(@RequestBody QueryApplyMO params) {
        String systemName = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        if(systemName.equals("admin")){
            systemName = null;
        }
        if (StringUtils.isNotEmpty(systemName)){
            params.setSystemSn(systemName);
        }
        Query query = params.getQuery();

        PagerModel<SolvedTaskVO> pm = iFlowableTaskService.getApplyedTasks(params, query);
        return pm;
    }

    /**
     * @Title: 获取当前任务下一任务列表
     */
    @GetMapping(value = "/next-nodes/{taskId}")
    @ApiOperation("获取当前任务下一任务列表")
    @ApiImplicitParam(name = "taskId", value = "任务ID", dataType = "String")
    public ReturnVO<NextChooseVO> getNextNodes(@PathVariable String taskId){
        return iFlowableBpmnModelService.findNextNodesByTaskId(taskId);
    }

    @GetMapping(value = "/now-node/{taskId}")
    @ApiOperation("获取当前任务的roid")
    @ApiImplicitParam(name = "taskId", value = "任务ID", dataType = "String")
    public ReturnVO<NextElementVO> getNowNode(@PathVariable String taskId){
        return iFlowableBpmnModelService.findNowNodeByTaskId(taskId);
    }

    /**
     * @Title: 审批任务
     */
    @PostMapping(value = "/do/complete")
    @ApiOperation("审批任务")
    @ApiImplicitParam(name = "params", value = "审批参数VO", dataType = "CompleteTaskMO")
    public ReturnVO complete(@RequestBody CompleteTaskMO params) {
        boolean flag = this.isSuspended(params.getBusinessKey());
        ReturnVO<String> returnVO = null;

        if (params.getVariables() == null){
            params.setVariables(new HashMap<String, Object>());
        }

        if (!flag){
//            params.setUserCode(this.getLoginUser().getId());
            if (taskService.getVariable(params.getTaskId(),"jumpNodeKey") != null){
                // 被驳回的单，要执行跳转
                String jumpNodeKey = taskService.getVariable(params.getTaskId(),"jumpNodeKey").toString();
                returnVO = iFlowableTaskService.jumpTask(params, jumpNodeKey);
            }else {
                // 普通审批
                returnVO = iFlowableTaskService.complete(params);
            }
        }else{
            returnVO = new ReturnVO<>(ReturnCode.FAIL,"流程已挂起，请联系管理员激活!");
        }
        return returnVO;
    }

    /**
     * @Title: 转办
     * @Description: A->B
     */
    @PostMapping(value = "/do/turn")
    @ApiOperation("转办")
    @ApiImplicitParam(name = "params", value = "转办参数VO", dataType = "TurnTaskMO")
    public ReturnVO turnTask(@RequestBody TurnTaskMO params) {
        ReturnVO<String> returnVO = null;
        String turnToUserId = params.getTurnToUserId();
        if (StringUtils.isNotBlank(turnToUserId)) {
//            params.setUserCode(this.getLoginUser().getId());
//            params.setTurnToUserId(userCodes[0]);
            returnVO = iFlowableTaskService.turnTask(params);
        }else {
            returnVO = new ReturnVO<>(ReturnCode.FAIL,"请选择人员");
        }
        return returnVO;
    }

    /**
     * @Title: 委派  A由于某些原因不能处理该任务，可以把任务委派给用户B代理，当B处理完之后再次回到用户A这里 A->B->A  A是任务的所有者，B是该任务的办理人
     */
    @PostMapping(value = "/do/delegate")
    @ApiOperation("委派")
    @ApiImplicitParam(name = "params", value = "委派参数VO", dataType = "DelegateTaskMO")
    public ReturnVO delegateTask(@RequestBody DelegateTaskMO params) {
        ReturnVO<String> returnVO = null;
        String delegateUserCode = params.getDelegateUserCode();
        if (StringUtils.isNotBlank(delegateUserCode)) {
//            params.setUserCode(this.getLoginUser().getId());
//            params.setTurnToUserId(userCodes[0]);
            returnVO = iFlowableTaskService.delegateTask(params);
        }else {
            returnVO = new ReturnVO<>(ReturnCode.FAIL,"请选择人员");
        }
        return returnVO;
    }

    /**
     * @Title: 签收
     * @Description: 一般情况就是多个候选人，或者候选组的情况下，要先把这个任务签收下来，以免别人又做了同样的任务。
     */
    @PostMapping(value = "/do/claim")
    @ApiOperation("签收")
    @ApiImplicitParam(name = "params", value = "签收VO", dataType = "ClaimTaskMO")
    public ReturnVO claimTask(@RequestBody ClaimTaskMO params) {
//        params.setUserCode(this.getLoginUser().getId());
        ReturnVO<String> returnVO = iFlowableTaskService.claimTask(params);
        return returnVO;
    }

    /**
     * @Title: 反签收
     * @Description: 就是把执行人设置为空，注意事项：反签收的时候，一定要先确认是否有候选人或候选组，如果没有的花，不能反签收，因为回导致这个任务无法认领。
     */
    @PostMapping(value = "/do/unClaim")
    @ApiOperation("反签收")
    @ApiImplicitParam(name = "params", value = "签收VO", dataType = "ClaimTaskMO")
    public ReturnVO unClaimTask(@RequestBody ClaimTaskMO params) {
//        params.setUserCode(this.getLoginUser().getId());
        ReturnVO<String> returnVO = iFlowableTaskService.unClaimTask(params);
        return returnVO;
    }

    /**
     * @Title: 向前加签
     * @Description: 本来任务是一个人审批，但是办理人觉得还需要另外的人来审批 看看， 就加签
     *                  向前加签  A-> B,C,D ->A
     */
    @PostMapping(value = "/do/beforeAddSign")
    @ApiOperation("向前加签")
    @ApiImplicitParam(name = "params", value = "加签VO", dataType = "AddSignTaskMO")
    public ReturnVO beforeAddSignTask(@RequestBody AddSignTaskMO params) {
        ReturnVO<String> returnVO = null;
        List<String> signPersoneds = params.getSignPersoneds();
        if (signPersoneds != null && signPersoneds.size() > 0) {
//            params.setUserCode(this.getLoginUser().getId());
//            params.setSignPersoneds(Arrays.asList(userCodes));
            returnVO = iFlowableTaskService.beforeAddSignTask(params);
        }else {
            returnVO = new ReturnVO<>(ReturnCode.FAIL,"请选择人员");
        }
        return returnVO;
    }

    /**
     * @Title: 向后加签
     *          A->B,C,D -> END
     */
    @PostMapping(value = "/do/afterAddSign")
    @ApiOperation("向后加签")
    @ApiImplicitParam(name = "params", value = "加签VO", dataType = "AddSignTaskMO")
    public ReturnVO afterAddSignTask(@RequestBody AddSignTaskMO params) {
        ReturnVO<String> returnVO = null;
        List<String> signPersoneds = params.getSignPersoneds();
        if (signPersoneds != null && signPersoneds.size() > 0) {
//            params.setUserCode(this.getLoginUser().getId());
//            params.setSignPersoneds(Arrays.asList(userCodes));
            returnVO = iFlowableTaskService.afterAddSignTask(params);
        }else {
            returnVO = new ReturnVO<>(ReturnCode.FAIL,"请选择人员");
        }
        return returnVO;
    }

    /**
     * @Title: 获取可回退节点列表
     */
    @GetMapping(value = "/backNodes/{businessKey}/{taskId}")
    @ApiOperation("获取可驳回节点列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "businessKey", value = "业务主键", dataType = "String"),
            @ApiImplicitParam(name = "taskId", value = "任务Id", dataType = "String")
    })
    public ReturnVO<List<FlowNodeVO>> getBackNodesByProcessInstanceId(@PathVariable String businessKey, @PathVariable String taskId) {
        String processInstanceId = this.rufindPorcInsByKey(businessKey);
        List<FlowNodeVO> datas = iFlowableTaskService.getBackNodesByProcessInstanceId(processInstanceId,taskId);
        ReturnVO<List<FlowNodeVO>> returnVO = new ReturnVO<>(ReturnCode.SUCCESS,"查询返回节点成功", datas);
        return returnVO;

    }

    @PostMapping(value = "/do/back")
    @ApiOperation("回退跳转")
    @ApiImplicitParam(name = "params", value = "回退VO", dataType = "BackTaskMO")
    public ReturnVO doBack(@RequestBody BackTaskMO params) {
        ReturnVO<String> returnVO = iFlowableTaskService.backToStepTask(params);
        return returnVO;
    }
}
